/**
* @file Timer.cpp
* @author Max Ocklind (original by "alex79roma" at http://www.cplusplus.com/forum/beginner/317/)
* @version 2010-01-11
*
* A simple timer class that can keep track of if a time limit has been exceeded.
**/


/* includes */

#include "Timer.h"


/* functions */


/* public */

/**
* Starts the timer if it is not already running.
*/
void Timer::start()
{
	if (!mRunning)
	{
		if (mResetted)
			mBeg  = (unsigned long) clock();
		else
			mBeg -= mEnd - (unsigned long) clock();
		
		mRunning  = true;
		mResetted = false;
	}
}

/**
* Sets the specified time limit and then starts the timer if it is not already running.
*
* @param timeLimit the time limit to keep track of
*/
void Timer::start(unsigned long timeLimit)
{
	setLimit(timeLimit);
	start();
}

/**
* Stops the timer if it is running.
*/
void Timer::stop()
{
	if (mRunning)
	{
		mEnd     = (unsigned long) clock();
		mRunning = false;
	}
}

/**
* Resets the timer and time limit.
*/
void Timer::reset()
{
	bool wereRunning = mRunning;

	if (wereRunning)
		stop();
	
	mResetted = true;
	mBeg      = 0;
	mEnd      = 0;
	mLimit	  = NO_TIME_LIMIT;
	
	if (wereRunning)
		start();
}

/**
* Checks if the timer is running.
*
* @return <code>true</code> if the timer is running, otherwise <code>false</code>
*/
bool Timer::isRunning()
{
	return mRunning;
}

/**
* Fetches the elapsed time of the timer in seconds.
*
* @return the elapsed time in seconds
*/
unsigned long Timer::getTime()
{
	if (mRunning)
		return ((unsigned long) clock() - mBeg) / CLOCKS_PER_SEC;
	else
		return (mEnd - mBeg) / CLOCKS_PER_SEC;
}

/**
* Checks if the elapsed time of the timer is greater than the specified number of seconds.
*
* @param seconds the number of seconds to compare against
* @return <code>true</code> if the elapsed time is greater than the specified number of seconds,
* otherwise <code>false</code>
*/
bool Timer::isOver(unsigned long seconds)
{
	return getTime() >= seconds;
}

/**
* Checks if the elapsed time is over the time limit.
*
* @return <code>true</code> if the time limit has been reached or exceeded, otherwise <code>false</code>
*/
bool Timer::isOverLimit()
{
	if (mLimit == NO_TIME_LIMIT)
		return false;

	return isOver(mLimit);
}

/**
* Sets the (non-negative) time limit to keep track of.
*
* @param seconds the length of the time limit in seconds
*/
void Timer::setLimit(unsigned long seconds)
{
	if (seconds >= 0)
		mLimit = seconds;
}

/**
* Fetches the currently stored time limit.
*
* @return the time limit in seconds
*/
unsigned long Timer::getLimit()
{
	return mLimit;
}